﻿using System;
using System.Collections.Generic;

namespace DotNetCommon.Extensions
{
    using DotNetCommon;
    using DotNetCommon.Accessors;
    using DotNetCommon.Data;
    using System;
    using System.Collections;
    using System.Collections.Concurrent;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Threading.Tasks;

    /// <summary>
    /// <see cref="IEnumerable{T}"/>扩展类，树形结构操作
    /// </summary>
    public static class TreeExtensions
    {
        #region Remove
        /// <summary>
        /// 从集合中删除元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="predicate"></param>
        /// <returns>返回自身</returns>
        public static ICollection<T> Remove<T>(this ICollection<T> collection, Func<T, bool> predicate)
        {
            if (collection == null) return collection;
            collection.Where(predicate).ToList().ForEach(t => collection.Remove(t));
            return collection;
        }
        #endregion

        #region ToTree
        /// <summary>
        /// 根据指定的父节点和当前节点标记，从集合中提取为树状结构数据(原集合数据不改变)
        /// </summary>
        /// <typeparam name="T">集合中的数据模型</typeparam>
        /// <typeparam name="TId">数据模型中表示唯一标识类型</typeparam>
        /// <param name="collection"></param>
        /// <param name="idSelector">如何识别当前的节点</param>
        /// <param name="parentIdSelector">如何识别父节点</param>
        /// <param name="rootId">父节点默认的标识值</param>
        /// <returns>新构建的TreeNode集合</returns>
        public static TreeNode<T>[] ToTree<T, TId>(this IEnumerable<T> collection,
            Func<T, TId> idSelector,
            Func<T, TId> parentIdSelector,
            TId rootId = default)
                => collection.Where(x => EqualityComparer<TId>.Default.Equals(parentIdSelector(x), rootId))
                    .Select(x => new TreeNode<T>(x, collection.ToTree(idSelector, parentIdSelector, idSelector(x))))
                    .ToArray();

        /// <summary>
        /// 根据指定的父节点和当前节点标记，从集合中提取为树状结构数据
        /// </summary>
        /// <typeparam name="T">集合中的数据模型</typeparam>
        /// <typeparam name="TId">数据模型中表示唯一标识类型</typeparam>
        /// <param name="collection"></param>
        /// <param name="idSelector">如何识别当前的节点</param>
        /// <param name="parentIdSelector">如何识别父节点</param>
        /// <param name="isRoot">判断是否是根节点</param>
        public static TreeNode<T>[] ToTree<T, TId>(this IEnumerable<T> collection,
            Func<T, TId> idSelector,
            Func<T, TId> parentIdSelector,
            Func<T, bool> isRoot)
        {
            return collection.Where(x => isRoot(x))
                       .Select(x => new TreeNode<T>(x, collection.ToTree(idSelector, parentIdSelector, t => EqualityComparer<TId>.Default.Equals(parentIdSelector(t), idSelector(x))).ToArray())).ToArray();
        }
        #endregion

        #region FetchToTree 
        /// <summary>
        /// 从扁平的集合数据中提取树状结构（原集合数据不变）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TId"></typeparam>
        /// <param name="collection"></param>
        /// <param name="idSelector">Id选择器,如: t=>t.Id</param>
        /// <param name="parentIdSelector">PId选择器,如: t=>t.PId</param>
        /// <param name="childrenSelectorExpression">子节点集合选择表达式，如: t=>t.Children</param>
        /// <param name="isRoot">用来判断是否是根节点(默认为null,即:使用TId的默认值)</param>
        /// <returns>提取出来的树状结构数据</returns>
        public static List<T> FetchToTree<T, TId>(this IEnumerable<T> collection,
           Func<T, TId> idSelector,
           Func<T, TId> parentIdSelector,
           Expression<Func<T, ICollection<T>>> childrenSelectorExpression,
           Func<T, bool> isRoot = null) where T : class
        {
            if (childrenSelectorExpression.Body is not MemberExpression) throw new Exception($"参数{nameof(childrenSelectorExpression)}必须是一个MemberExpression，如: t=>t.Children");
            var member = childrenSelectorExpression.Body as MemberExpression;
            var prop = typeof(T).GetProperty(member.Member.Name);
            return _fetchToTree(collection, idSelector, parentIdSelector, isRoot, prop).ToList();
        }

        /// <summary>
        /// 从扁平的集合数据中提取树状结构（原集合数据不变）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="idPropName">Id属性名字, 如: "Id"</param>
        /// <param name="parentIdPropName">PId属性名称, 如: "ParentId"</param>
        /// <param name="childrenPropName">子节点属性名字, 如: "Children"</param>
        /// <param name="compare">用来比较 Id 是否等于 ParentId, 如: EqualityComparer&lt;int>.Default</param>
        /// <param name="isRoot">用来判断是否是根节点(默认为null,即:使用TId的默认值)</param>
        /// <returns>提取出来的树状结构数据</returns>
        public static List<T> FetchToTree<T>(this IEnumerable<T> collection,
           string idPropName,
           string parentIdPropName,
           string childrenPropName,
           IEqualityComparer compare = null,
           Func<T, bool> isRoot = null) where T : class
        {
            var props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            var prop = props.Where(i => i.Name == childrenPropName).FirstOrDefault().IfNullUse(props.Where(i => string.Equals(i.Name, childrenPropName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault());
            if (prop == null) throw new Exception($"class: {typeof(T).GetClassFullName()} 中不存在参数 {nameof(childrenPropName)} 指定的属性名称!");

            var accessor = Accessor.Build<T>(true);
            var parentIdType = props.FirstOrDefault(i => i.Name == parentIdPropName) ?? props.FirstOrDefault(i => string.Equals(i.Name, parentIdPropName));
            if (parentIdType == null) throw new Exception($"class: {typeof(T).GetClassFullName()} 中不存在参数 {nameof(parentIdPropName)} 指定的属性名称!");

            if (compare == null) compare = parentIdType.PropertyType.GetDefaultEqualityComparer();
            return _fetchToTree(collection, obj => accessor[obj, idPropName], obj => accessor[obj, parentIdPropName], isRoot, prop, compare).ToList();
        }

        /// <summary>
        /// 将扁平的集合数据转为树状结构（原集合数据不变）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TId"></typeparam>
        /// <param name="collection"></param>
        /// <param name="idSelector">Id选择器,如: t=>t.Id</param>
        /// <param name="parentIdSelector">PId选择器,如: t=>t.PId</param>
        /// <param name="isRoot">用来判断是否是根节点(默认为null,即:使用TId的默认值)</param>
        /// <returns>提取出来的树状结构数据</returns>
        public static List<T> FetchToTree<T, TId>(this IEnumerable<T> collection,
           Func<T, TId> idSelector,
           Func<T, TId> parentIdSelector,
           Func<T, bool> isRoot = null) where T : class, ITreeStruct<T>
        {
            var prop = typeof(ITreeStruct<T>).GetProperty("Children");
            return _fetchToTree(collection, idSelector, parentIdSelector, isRoot, prop).ToList();
        }

        private static ConcurrentDictionary<Type, object> _cacheCompare = new();
        private static ICollection<T> _fetchToTree<T, TId>(this IEnumerable<T> collection,
           Func<T, TId> idSelector,
           Func<T, TId> parentIdSelector,
           Func<T, bool> isRoot,
           PropertyInfo prop,
           IEqualityComparer compare = null) where T : class
        {
            compare ??= _cacheCompare.GetOrAdd(typeof(TId), _ => EqualityComparer<TId>.Default) as EqualityComparer<TId>;
            var accessor = Accessor.Build<T>();
            var childrenName = prop.Name;
            var roots = new List<T>(8);
            var list = new List<T>(collection.Count());
            if (isRoot == null)
            {
                //没有筛选父节点的逻辑, 则任意节点都可能作为父节点
                /* 算法:
                 * 一开始有 totalList: 这是所有的平铺数据
                 * 
                 * 初始遍历, 两两比较, 发现父子关系后将儿子移动父亲的容器里, 并且在新生儿列表(叫它"新生儿列表A"吧)中记录一下;
                 * 为什么要有"新生儿列表A", 因为将儿子移动到父亲容器后, 它就失去做为父亲的机会, 所以还要接着给这些新生儿找儿子;
                 * 
                 * 接下来就是递归的东西了:
                 *      在 totalList 中为 "新生儿列表A" 找儿子, 找到后将儿子移动的父亲的容器中, 并记录在新的新生儿列表中(叫它"新生儿列表B"吧);
                 *      给"新生儿列表A"找完儿子后, 再去看 "新生儿列表B" 是否有元素, 有的话,继续为 "新生儿列表B" 找儿子, 找到后产生 "新生儿列表C", 依次类推, 直到不再产生新的新生儿列表为止
                 */

                //初始遍历
                var totalList = collection.ToList();
                var newChilren = new List<T>();
                for (int i = 0; i < totalList.Count - 1; i++)
                {
                    for (int j = i + 1; j < totalList.Count; j++)
                    {
                        if (compare.Equals(parentIdSelector(totalList[j]), idSelector(totalList[i])))
                        {
                            var children = accessor[totalList[i], childrenName] as ICollection<T>;
                            if (children == null) accessor[totalList[i], childrenName] = children = new List<T>();
                            children.Add(totalList[j]);
                            newChilren.Add(totalList[j]);
                            totalList.RemoveAt(j);
                            j--;
                            continue;
                        }
                        else if (compare.Equals(parentIdSelector(totalList[i]), idSelector(totalList[j])))
                        {
                            var children = accessor[totalList[j], childrenName] as ICollection<T>;
                            if (children == null) accessor[totalList[j], childrenName] = children = new List<T>();
                            children.Add(totalList[i]);
                            newChilren.Add(totalList[i]);
                            totalList.RemoveAt(i);
                            i--;
                            break;
                        }
                    }
                }
                // 递归：
                // newChildren2: 循环中产生的 "新生儿列表B、新生儿列表C等",知道不产生为止
                var newChildren2 = newChilren;
                while (newChildren2.Count > 0)
                {
                    var newChildren3 = new List<T>();
                    for (int i = 0; i < newChildren2.Count; i++)
                    {
                        for (int j = 0; j < totalList.Count; j++)
                        {
                            if (compare.Equals(parentIdSelector(totalList[j]), idSelector(newChildren2[i])))
                            {
                                var children = accessor[newChildren2[i], childrenName] as ICollection<T>;
                                if (children == null) accessor[newChildren2[i], childrenName] = children = new List<T>();
                                children.Add(totalList[j]);
                                newChildren3.Add(totalList[j]);
                                totalList.RemoveAt(j);
                                j--;
                            }
                        }
                    }
                    newChildren2 = newChildren3;
                }

                return totalList;
            }
            //有根节点的选取逻辑, 先提取父节点
            foreach (var item in collection)
            {
                if (isRoot(item)) roots.Add(item);
                else list.Add(item);
            }
            FetchChildren(roots, list, idSelector, parentIdSelector);
            return roots;
            void FetchChildren(List<T> parents, List<T> collection,
                Func<T, TId> idSelector,
                Func<T, TId> parentIdSelector)
            {
                //新的父级节点
                var newParents = new List<T>();
                for (var i = 0; i < collection.Count; i++)
                {
                    var item = collection[i];
                    foreach (var parent in parents)
                    {
                        var children = accessor[parent, childrenName] as ICollection<T>;
                        if (children == null) accessor[parent, childrenName] = children = new List<T>();
                        if (compare.Equals(parentIdSelector(item), idSelector(parent)))
                        {
                            children.Add(item);
                            newParents.Add(item);
                            collection.RemoveAt(i);
                            i--;
                            break;
                        }
                    }
                }
                //产生了新的父级 再递归调用
                if (newParents.Count > 0) FetchChildren(newParents, collection, idSelector, parentIdSelector);
            }
        }
        #endregion

        #region ToFlat
        /// <summary>
        /// 将任意多级的树形列表展开(返回新的平铺集合，当treeToFlatAction参数为SetEmpty时原集合的Children属性被重置)
        /// </summary>
        /// <param name="srcArr">原属树形表</param>
        /// <param name="childrenSelectorExpression">获取子节点集合</param>
        /// <param name="treeToFlatAction">转为平铺数据后,针对原集合元素的Children属性的设置,默认为none,即:不设置</param>
        /// <returns></returns>
        public static List<T> ToFlat<T>(this IEnumerable<T> srcArr, Expression<Func<T, IEnumerable<T>>> childrenSelectorExpression, TreeToFlatAction treeToFlatAction = TreeToFlatAction.None)
        {
            if (childrenSelectorExpression.Body is not MemberExpression) throw new Exception($"参数{nameof(childrenSelectorExpression)}必须是一个MemberExpression，如: t=>t.Children");
            var member = childrenSelectorExpression.Body as MemberExpression;
            var prop = typeof(T).GetProperty(member.Member.Name);
            var getChildren = childrenSelectorExpression.Compile();

            var res = _ToFlat(srcArr);
            if (treeToFlatAction == TreeToFlatAction.SetEmpty)
            {
                res.ForEach(i =>
                {
                    var children = getChildren(i);
                    //如果为null则不作更改
                    if (children == null) return;
                    //如果为ICollection,直接清空
                    if (children is ICollection<T> collection)
                    {
                        collection.Clear();
                    }
                    else if (prop.CanWrite && children is IEnumerable<T>)
                    {
                        prop.SetValue(i, new T[0]);
                    }
                });
            }
            else if (treeToFlatAction == TreeToFlatAction.SetNull)
            {
                if (prop.CanWrite)
                {
                    res.ForEach(i =>
                    {
                        if (getChildren(i) != null)
                        {
                            prop.SetValue(i, null);
                        }
                    });
                }
            }
            else if (treeToFlatAction == TreeToFlatAction.SetEmptyCollection)
            {
                if (prop.CanWrite)
                {
                    res.ForEach(i =>
                    {
                        var children = getChildren(i);
                        if (children == null)
                        {
                            prop.SetValue(i, new List<T>());
                        }
                        else
                        {
                            //如果为ICollection,直接清空
                            if (children is ICollection<T> collection)
                            {
                                collection.Clear();
                            }
                            else if (prop.CanWrite && children is IEnumerable<T>)
                            {
                                //如果为数组或IEnumerable则设为空数组
                                prop.SetValue(i, new T[0]);
                            }
                        }
                    });
                }
            }
            return res;

            List<T> _ToFlat(IEnumerable<T> srcArr)
            {
                var res = new List<T>();
                if (srcArr != null && srcArr.Count() > 0)
                {
                    srcArr.ForEach(i =>
                    {
                        res.Add(i);
                        var children = getChildren(i);
                        if (children != null && children.Count() > 0)
                        {
                            var list = _ToFlat(children);
                            if (list != null && list.Count > 0) res.AddRange(list);
                        }
                    });
                }
                return res;
            }
        }
        #endregion

        #region FilterTree
        /// <summary>
        /// 过滤树结构(注意原始集合已改变)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tree"></param>
        /// <param name="childrenSelector"></param>
        /// <param name="filterExpression">单个节点的过滤条件</param>
        /// <param name="withAllChildren">当单个节点通过后是否直接连带子节点到输出结果树中</param>
        /// <param name="tmpList">临时存放分支上首个命中节点</param>
        /// <remarks>过滤的过程是在原树形集合上做减法</remarks>
        /// <returns>返回自身</returns>
        private static void FilterTree<T>(this IList<T> tree, Func<T, IList<T>> childrenSelector, Predicate<T> filterExpression, bool withAllChildren, List<T> tmpList)
        {
            //倒序遍历,方便移除
            for (var i = tree.Count - 1; i >= 0; i--)
            {
                var child = tree[i];
                var showme = false;
                if (filterExpression(child))
                {
                    showme = true;
                    if (tmpList != null) tmpList.Add(child);
                }
                //当前节点已命中且指定返回所有子节点,可以直接返回了
                if (withAllChildren && showme) continue;
                var showchild = false;
                var children = childrenSelector(child);
                if (children != null && children.Count > 0)
                {
                    FilterTree(children, childrenSelector, filterExpression, withAllChildren, showme ? null : tmpList);
                    if (children.Count > 0)
                    {
                        showchild = true;
                    }
                }
                if (showme == false && showchild == false)
                {
                    //自身和字节点均没有被命中，则移除自身
                    tree.RemoveAt(i);
                }
            }
        }

        /// <summary>
        /// 过滤树结构(注意原始集合已改变)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tree"></param>
        /// <param name="childrenSelector"></param>
        /// <param name="filterExpression">单个节点的过滤条件</param>
        /// <param name="withAllChildren">当单个节点通过后是否直接连带子节点到输出结果树中</param>
        /// <param name="withAllParents">当单个节点通过后是否输出当前节点的所有父节点到结果树中</param>
        /// <remarks>过滤的过程是在原树形集合上做减法</remarks>
        /// <returns>返回自身</returns>
        public static List<T> FilterTree<T>(this IList<T> tree, Func<T, IList<T>> childrenSelector, Predicate<T> filterExpression, bool withAllChildren = false, bool withAllParents = true)
        {
            List<T> tmpList = null;
            if (!withAllParents)
            {
                //不输出父节点,则收集分支上首个命中的节点
                tmpList = new List<T>();
            }
            FilterTree(tree, childrenSelector, filterExpression, withAllChildren, tmpList);
            if (withAllParents) return tree.ToList();
            else
            {
                tree.Clear();
                tree.AddRange(tmpList);
                return tree.ToList();
            }
        }
        #endregion

        #region RecurseTree VisitTree
        /// <summary>
        /// 已改名,请使用 <seealso cref="VisitTree{T}(ICollection{T}, Func{T, IEnumerable{T}}, Action{VisitTreeContext{T}})"/>
        /// </summary>
        [Obsolete]
        public static List<T> RecurseTree<T>(this ICollection<T> tree, Func<T, IEnumerable<T>> childrenSelector, Action<VisitTreeContext<T>> action) where T : class
            => VisitTree(tree, childrenSelector, action);

        /// <summary>
        /// 递归树结构
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tree"></param>
        /// <param name="childrenSelector"></param>
        /// <param name="action">节点处理逻辑(node:当前节点,isLeaf:是否是叶子节点,deepIndex:深度索引,parents:父节点集合)</param>
        /// <returns>返回自身</returns>
        public static List<T> VisitTree<T>(this ICollection<T> tree, Func<T, IEnumerable<T>> childrenSelector, Action<VisitTreeContext<T>> action) where T : class
        {
            var list = tree.ToList();
            foreach (var node in list)
            {
                var children = childrenSelector(node);
                var isLeaf = children == null || children.Count() == 0;
                var ctx = new VisitTreeContext<T>()
                {
                    Current = node,
                    IsLeaf = isLeaf,
                    Parent = null
                };
                _recurseTree(ctx);
                if (ctx.BreakRquested) break;
            }
            return list;

            void _recurseTree(VisitTreeContext<T> ctx)
            {
                action(ctx);
                //中断遍历
                if (ctx.BreakRquested)
                {
                    if (ctx.Parent != null) ctx.Parent.BreakRquested = true;
                    return;
                }
                //继续下个兄弟节点遍历
                if (ctx.NextSiblingRquested)
                {
                    //遍历完当前节点的后续逻辑
                    ctx.RunAfterAct?.Invoke();
                    return;
                }
                if (!ctx.IsLeaf)
                {
                    //遍历子节点
                    //先把自身加入上下文
                    ctx.Parents.Add(ctx.Current);
                    var children = childrenSelector(ctx.Current);
                    foreach (var n in children)
                    {
                        //深度+1
                        ctx.InternalConter.Deep++;
                        var childrenNew = childrenSelector(n);
                        var isLeafNew = childrenNew == null || childrenNew.Count() == 0;
                        var newCtx = new VisitTreeContext<T>
                        {
                            Current = n,
                            IsLeaf = isLeafNew,
                            Parent = ctx
                        };
                        //递归调用
                        _recurseTree(newCtx);
                        //深度-1
                        ctx.InternalConter.Deep--;
                        if (newCtx.BreakRquested)
                        {
                            if (newCtx.Parent != null) newCtx.Parent.BreakRquested = true;
                            return;
                        }
                    }
                    //把自身从上下文中移除
                    var index = ctx.Parents.LastIndexOf(ctx.Current);
                    ctx.Parents.RemoveAt(index);
                }
                //遍历完当前节点的后续逻辑
                ctx.RunAfterAct?.Invoke();
            }
        }

        /// <summary>
        /// 递归树结构
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tree"></param>
        /// <param name="childrenPropName">子节点集合的属性名称,如: "Children"</param>
        /// <param name="action">节点处理逻辑(node:当前节点,isLeaf:是否是叶子节点,deepIndex:深度索引,parents:父节点集合)</param>
        /// <returns>返回自身</returns>
        public static List<T> VisitTree<T>(this ICollection<T> tree, string childrenPropName, Action<VisitTreeContext<T>> action) where T : class
        {
            Ensure.NotNull(childrenPropName, nameof(childrenPropName));
            var accessor = Accessor.Build<T>(true, false);
            return VisitTree<T>(tree, t => accessor[t, childrenPropName] as IEnumerable<T>, action);
        }
        #endregion
    }

    /// <summary>
    /// ICollection.ToFlat()方法的参数
    /// </summary>
    public enum TreeToFlatAction
    {
        /// <summary>
        /// 不对原有的Children属性做任何操作
        /// </summary>
        None,
        /// <summary>
        /// 设置为空集合(原来的Children为null则为null，否则为空集合)
        /// </summary>
        SetEmpty,
        /// <summary>
        /// 设置为空集合(将原来的Children设为null)
        /// </summary>
        SetNull,
        /// <summary>
        /// 设置为空集合(将原来的Children设为元素个数为空的集合)
        /// </summary>
        SetEmptyCollection
    }

    /// <summary>
    /// 树节点遍历上下文
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class VisitTreeContext<T>
    {
        /// <summary>
        /// 当前节点
        /// </summary>
        public T Current { get; internal set; }
        /// <summary>
        /// 当前节点深度,从0开始
        /// </summary>
        public int DeepIndex => InternalConter.Deep;
        /// <summary>
        /// 当前节点是否是叶子节点
        /// </summary>
        public bool IsLeaf { get; internal set; }

        private List<T> _parents = null;
        /// <summary>
        /// 当前节点的父节点集合
        /// </summary>
        /// <remarks>注意: 一条线共用一个集合，所以不要在这里增减上面的内容, 可以使用 ctx.Parents.ToList() 产生新的集合</remarks>
        public List<T> Parents
        {
            get
            {
                if (_parents == null)
                {
                    // _parents: 其实这个属性只有在根节点才有值
                    if (Parent == null || Parent.Parents == null) _parents = new List<T>();
                    else _parents = Parent.Parents;
                }
                return _parents;
            }
        }

        /// <summary>
        /// 当前节点的父节点集合(包含自身)
        /// </summary>
        public List<T> ParentsWithSelf
        {
            get
            {
                var arr = new T[Parents.Count];
                Parents.CopyTo(arr);
                var list = arr.ToList();
                list.Add(Current);
                return list;
            }
        }

        /// <summary>
        /// 中断遍历
        /// </summary>
        public void BreakRecurse()
        {
            BreakRquested = true;
        }

        /// <summary>
        /// 继续下个兄弟节点的遍历(跳过子节点)
        /// </summary>
        public void NextSibling()
        {
            NextSiblingRquested = true;
        }

        internal Action RunAfterAct { get; set; }
        /// <summary>
        /// 当完成此节点遍历后再执行的逻辑
        /// </summary>
        /// <param name="act"></param>
        public void RunAfter(Action act)
        {
            RunAfterAct = act;
        }

        /// <summary>
        /// 是否请求中断遍历
        /// </summary>
        internal bool BreakRquested { set; get; }

        /// <summary>
        /// 是否请求继续下个兄弟节点遍历
        /// </summary>
        internal bool NextSiblingRquested { set; get; }

        /// <summary>
        /// 父节点
        /// </summary>
        internal VisitTreeContext<T> Parent { get; set; }

        private Counter _counter = null;
        /// <summary>
        /// 深度(仅存储在根节点)
        /// </summary>
        internal Counter InternalConter
        {
            get
            {
                if (_counter == null)
                {
                    if (Parent == null || Parent.InternalConter == null) _counter = new Counter();
                    else _counter = Parent.InternalConter;
                }
                return _counter;
            }
        }
    }

    internal class Counter
    {
        public int Deep { get; set; }
    }

}